﻿
// DBBrowserView.cpp: CDBBrowserView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "DBBrowser.h"
#endif

#include "DBBrowserDoc.h"
#include "DBBrowserView.h"
#include "CellRichEdit.h"
#include "dbother.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDBBrowserView

IMPLEMENT_DYNCREATE(CDBBrowserView, CView)

BEGIN_MESSAGE_MAP(CDBBrowserView, CView)
	ON_WM_CONTEXTMENU()
	//ON_WM_RBUTTONUP()
	ON_WM_SIZE()
	ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST1, &CDBBrowserView::OnGetdispinfoList1)
	ON_NOTIFY(LVN_ENDSCROLL, IDC_LIST1, &CDBBrowserView::OnEndscrollList1)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CDBBrowserView::OnDblclkList1)
	ON_NOTIFY(NM_CLICK, IDC_LIST1, &CDBBrowserView::OnClickkList1)
	ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CDBBrowserView::OnClickkList1)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CDBBrowserView::OnItemChangedList1)
	ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, &CDBBrowserView::OnColumnclickList1)
	ON_WM_TIMER()
	ON_WM_DROPFILES()
END_MESSAGE_MAP()

BEGIN_MESSAGE_MAP(CDBListCtrl, CListCtrl)
	ON_WM_HOTKEY()
	ON_WM_TIMER()
	ON_EN_KILLFOCUS(IDC_EDIT1, &CDBListCtrl::OnEnKillfocusEdit1)
END_MESSAGE_MAP()
// CDBBrowserView 构造/析构

CDBBrowserView::CDBBrowserView() noexcept
{
	// TODO: 在此处添加构造代码

}

CDBBrowserView::~CDBBrowserView()
{
}

BOOL CDBBrowserView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CDBBrowserView 绘图

void CDBBrowserView::OnDraw(CDC* /*pDC*/)
{
	CDBBrowserDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
}


void CDBBrowserView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
	//theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
}


// CDBBrowserView 诊断

#ifdef _DEBUG
void CDBBrowserView::AssertValid() const
{
	CView::AssertValid();
}

void CDBBrowserView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDBBrowserDoc* CDBBrowserView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDBBrowserDoc)));
	return (CDBBrowserDoc*)m_pDocument;
}
#endif //_DEBUG


// CDBBrowserView 消息处理程序

void CDBBrowserView::OnInitialUpdate()
{
	CView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	DragAcceptFiles(TRUE);
	CRect rc;
	GetClientRect(&rc);
	m_List.Create(WS_VISIBLE | ES_LEFT | LVS_REPORT | LVS_OWNERDATA, rc, this, IDC_LIST1);
	m_List.m_Edit.Create(WS_VISIBLE | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL, CRect(0, 0, 10, 10), &m_List, IDC_EDIT1);
	m_List.m_Edit.ShowWindow(SW_HIDE);
	CFont *pfont = m_List.GetFont();
	m_List.m_Edit.SetFont(pfont);
	SetWindowTheme(m_List.m_hWnd, L"Explorer", 0);
	m_List.SetExtendedStyle(m_List.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER);
	m_List.ShowWindow(SW_SHOW);
	SetTimer(999, 120000, 0);
}

void CDBBrowserView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	if (m_List && nType != SIZE_MINIMIZED) {
		CRect rc;
		GetClientRect(rc);
		m_List.MoveWindow(&rc, TRUE);
	}
}


void CDBBrowserView::OnGetdispinfoList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	CDBBrowserDoc *pDoc = GetDocument();
	int iItemIndex = (pDispInfo->item.iItem) % (pDoc->m_pagesize);
	int pageIndex = (pDispInfo->item.iItem) / (pDoc->m_pagesize);
	int iSubItemIndex = pDispInfo->item.iSubItem;

	if (pDispInfo->item.mask & LVIF_TEXT) //字符串缓冲区有效
	{
		if (pDoc->m_data.find(pageIndex) == pDoc->m_data.end()) {
			if (pDoc->m_datathread == nullptr) {
				if (pDoc->m_time < 50) { pDoc->GetPageData(); goto showdata; }
				else { pDoc->m_datathread = AfxBeginThread(GetPageDataByThread, pDoc); }
			}
			else { SetTimer(1, 20, 0); }
		}
		else {
			showdata:
			if (iItemIndex < pDoc->m_data[pageIndex].size()) {
				std::wstring *p = &pDoc->m_data[pageIndex][iItemIndex][iSubItemIndex];
				if (p->size() >= pDispInfo->item.cchTextMax) {
					lstrcpy(pDispInfo->item.pszText, p->substr(0, pDispInfo->item.cchTextMax - 1).data());
				}
				else { pDispInfo->item.pszText = (LPWSTR)p->data(); }
			}
			else if (pDoc->m_datathread == nullptr) {
				pDoc->m_itemcount = pDispInfo->item.iItem;
				m_List.SetItemCount(pDoc->m_itemcount);
				if (pDoc->m_itemcount){ m_List.EnsureVisible(pDoc->m_itemcount - 1, FALSE); }
			}
		}
	}
	*pResult = 0;
}


void CDBBrowserView::OnEndscrollList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	// TODO: 在此处添加实现代码.
	// LPNMLVSCROLL pStateChanged = reinterpret_cast<LPNMLVSCROLL>(pNMHDR);
	SetTimer(1, 20, 0);
}


void CDBBrowserView::UpdateRichEdit()
{
	CRichEditCtrl *edit = (CRichEditCtrl*)(((CFrameWndEx*)AfxGetMainWnd())->GetPane(ID_RICH_PANE)->GetDlgItem(ID_EDIT_CELL));
	auto pDoc = GetDocument();
	m_focus.iItem = min(m_focus.iItem, pDoc->m_itemcount);
	int page = m_focus.iItem / pDoc->m_pagesize;
	int iItem = m_focus.iItem % pDoc->m_pagesize;
	if (m_focus.iItem < 0 || m_focus.iItem >= pDoc->m_itemcount || pDoc->m_data.find(page) == pDoc->m_data.end()) {
		m_focus.changed = false; edit->SetWindowTextW(L"");
	}
	else {
		m_focus.changed = pDoc->m_rowid > -1 && m_focus.iItem > -1 && m_focus.iSubItem != pDoc->m_rowid
			&& m_List.GetSelectedCount() == 1;
		edit->SetWindowTextW(pDoc->m_data[page][iItem][m_focus.iSubItem].data());
	}
	((CellRichEdit*)((CFrameWndEx*)AfxGetMainWnd())->GetPane(ID_RICH_PANE))->m_changed = false;
}


void CDBBrowserView::OnClickkList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此处添加实现代码.
	m_focus.iItem = pNMItemActivate->iItem;
	m_focus.iSubItem = pNMItemActivate->iSubItem;
	if (m_focus.iItem > -1) { UpdateRichEdit(); }
}


void CDBBrowserView::OnDblclkList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此处添加实现代码.
	EditCell(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
}


void CDBBrowserView::OnItemChangedList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	auto pDoc = GetDocument();
	m_focus.iItem = pNMItemActivate->iItem;
	auto k = ::GetKeyState(VK_LBUTTON);
	if (m_focus.iItem > -1 && ::GetKeyState(VK_LBUTTON) >= 0 && ::GetKeyState(VK_RBUTTON) >= 0) { UpdateRichEdit(); }
}


void CDBBrowserView::OnColumnclickList1(NMHDR * pNMHDR, LRESULT * pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此处添加实现代码.
	
	LV_COLUMN lvc;
	TCHAR szText[16];
	lvc.mask = LVCF_TEXT;
	lvc.pszText = szText;
	lvc.cchTextMax = 16;
	m_List.GetColumn(pNMItemActivate->iSubItem, &lvc);
	CDBBrowserDoc *pDoc = GetDocument();
	std::string order = " order by " + sqlite::utility::utf16_to_utf8(lvc.pszText);
	pDoc->m_sql_order = order + (pDoc->m_sql_order != order + " desc" ? " desc" : "");
	pDoc->databaseadapter(pDoc->m_sql_select + pDoc->m_sql_where + pDoc->m_sql_order, false);
}

void CDBBrowserView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (nIDEvent == 1) { ReFresh(); KillTimer(1); }
	else if (nIDEvent == 4) {
		KillTimer(4);
		auto pDoc = (CDBBrowserDoc*)GetDocument();
		pDoc->databaseadapter(pDoc->m_sql, false);
		ReFresh();
	}
	else if (nIDEvent == 3) {
		KillTimer(3);
		auto pStatusBar = (CMFCRibbonStatusBar*)((CFrameWndEx*)AfxGetMainWnd())->GetPane(AFX_IDW_STATUS_BAR);
		auto pT = pStatusBar->FindElement(ID_STATUSBAR_PANE1);
		pT->SetText(L""); pT->Redraw();
	}
	else if (nIDEvent == 2) {
		auto pStatusBar = (CMFCRibbonStatusBar*)((CFrameWndEx*)AfxGetMainWnd())->GetPane(AFX_IDW_STATUS_BAR);
		auto pProgressBar = (CMFCRibbonProgressBar*)(pStatusBar->FindElement(ID_STATUSBAR_PROGRESS));
		auto pDoc = GetDocument();
		auto pT = pStatusBar->FindElement(ID_STATUSBAR_PANE1);
		size_t comps = 0;
		for (int i = 0; i < pDoc->m_task->comp.size(); i++) {
			comps += pDoc->m_task->comp[i];
		}
		double per = (double)comps / pDoc->m_task->total * 100;
		if (pDoc->m_task->tasks > 0){
			pProgressBar->SetPos((int)per);
			per = (100 - per) / per * (clock() - pDoc->m_task->begin);
			int s = per / 1000, m = s / 60; s = s % 60;
			CString t;
			if (m) { t.Format(_T("剩余时间：%d分%d秒"), m, s); }
			else { t.Format(_T("剩余时间：%d秒"), s); }
			pT->SetText(t);
			pT->Redraw();
		}
		else {
			int ms = pDoc->m_task->end - pDoc->m_task->begin;
			int s = ms / 1000, m = s / 60;
			s = s % 60, ms = ms % 1000;
			CString ts;
			if (m) { ts.Format(_T("完成用时：%d分%d秒"), m, s); }
			else if (s){ ts.Format(_T("完成用时：%d秒%d"), s, ms); }
			else { ts.Format(_T("完成用时：%d ms"), ms); }
			KillTimer(2); pProgressBar->SetPos(100);
			if (pDoc->m_task->fresh) { pDoc->databaseadapter(pDoc->m_sql, false); }
			delete pDoc->m_task; pDoc->m_task = nullptr;
			pT->SetText(ts); pT->Redraw();
			SetTimer(3, 10000, 0);
		}
	}
	else if (nIDEvent == 999) {
		if (IsWindowVisible())
			KillTimer(nIDEvent);
		else
			AfxGetMainWnd()->SendMessage(WM_CLOSE);
	}
	CView::OnTimer(nIDEvent);
}

void CDBBrowserView::ReFresh()
{
	// TODO: 在此处添加实现代码.
	int top = m_List.GetTopIndex();
	int bottom = top + m_List.GetCountPerPage();
	m_List.SetRedraw(FALSE);
	m_List.RedrawItems(top, bottom);
	AdjustListWidth();
	m_List.SetRedraw(TRUE);
}

void CDBBrowserView::AdjustListWidth()
{
	// TODO: 在此处添加实现代码.
	CHeaderCtrl *p = m_List.GetHeaderCtrl();
	if (p != 0)
	{
		CRect rc;
		GetClientRect(rc);
		int width = rc.Width(), t = 0;
		int columncount = p->GetItemCount();
		
		for (int i = 0; i < columncount - 1; i++)
		{
			m_List.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
			int w = m_List.GetColumnWidth(i);
			if (w < 100) { m_List.SetColumnWidth(i, 100); t += 100; }
			else if (w > 2 * width / columncount) { m_List.SetColumnWidth(i, 2 * width / columncount); t += 2 * width / columncount; }
			else { t += w; }
		}
		m_List.SetColumnWidth(columncount - 1, LVSCW_AUTOSIZE);
		int w = m_List.GetColumnWidth(columncount - 1);
		if (w < 100) { m_List.SetColumnWidth(columncount - 1, 100); }
		else if (t<width*0.95&&t + w>width) { m_List.SetColumnWidth(columncount - 1, width * 0.95 - t); }
		else if (w > 2 * width / columncount) { m_List.SetColumnWidth(columncount - 1, 2 * width / columncount); }
	}
}

void CDBListCtrl::OnEnKillfocusEdit1()
{
	// TODO: 在此处添加消息处理程序代码
	if (!m_Edit.IsWindowVisible()) { return; }
	CDBBrowserView *parent = (CDBBrowserView*)GetParent();
	CDBBrowserDoc *pDoc = parent->GetDocument();
	m_Edit.ShowWindow(SW_HIDE);
	if (errcode) { pDoc->m_newrow = false; return; }
	if (hotkey != 0x1B || pDoc->m_newrow) {
		CString newtext;
		m_Edit.GetWindowText(newtext);
		if (pDoc->m_data.find(pageIndex) != pDoc->m_data.end()
			&& (iItemIndex > -1 && iItemIndex < pDoc->m_data[pageIndex].size())
			&& (iSubItem > -1 && iSubItem < pDoc->m_data[pageIndex][iItemIndex].size())
			&& (newtext != ItemText || pDoc->m_newrow)) {
			LV_COLUMN lvc;
			TCHAR szText[16];
			lvc.mask = LVCF_TEXT;
			lvc.pszText = szText;
			lvc.cchTextMax = 16;
			GetColumn(iSubItem, &lvc);
			try {
				if (pDoc->m_autotrans && !pDoc->m_transaction) {
					pDoc->m_db << "begin;";
					pDoc->m_transaction=true;
				}
				CString sql;
				if (pDoc->m_newrow && newtext.GetLength() == 0) {
					sql.Format(_T("delete from %s where _rowid_ = %s;"), pDoc->m_table, pDoc->m_data[pageIndex][iItemIndex][pDoc->m_rowid].data());
					pDoc->m_db << sql;
					pDoc->m_data[pageIndex].pop_back();
					auto it = pDoc->m_data.find(pageIndex);
					if (it->second.size() == 0) { pDoc->m_data.erase(it); }
					pDoc->m_itemcount--; pDoc->m_rowcount--;
					SetItemCount(pDoc->m_itemcount);
					auto pStatusBar = (CMFCRibbonStatusBar*)((CFrameWndEx*)AfxGetMainWnd())->GetPane(AFX_IDW_STATUS_BAR);
					auto pStatusBarPane = (CMFCRibbonStatusBarPane*)(pStatusBar->FindElement(ID_STATUSBAR_PANE2));
					CString jls;
					jls.Format(_T("共%d条"), pDoc->m_rowcount);
					pStatusBarPane->SetText(jls);
				}
				else if (pDoc->m_newrow == 1 && std::wstring(lvc.pszText) == L"value") {
					std::wstring v = std::wstring(newtext.GetString());
					std::wstring k = pDoc->m_codegen->GetCode(v)[0];
					if (pDoc->m_table.Find(_T("'pinyin'")) != -1) {
						sql.Format(_T("update %s set jp = ? , key = ? , value = ? where _rowid_ = %s;"), pDoc->m_table, pDoc->m_data[pageIndex][iItemIndex][pDoc->m_rowid].data());
						std::wstring szmstr = dbother::getpyszm(k);
						pDoc->m_db << sql
							<< szmstr
							<< k
							<< v;
						if (pDoc->m_pyjp > -1) { pDoc->m_data[pageIndex][iItemIndex][pDoc->m_pyjp] = szmstr; }
					}
					else {
						sql.Format(_T("update %s set key = ? , value = ? where _rowid_ = %s;"), pDoc->m_table, pDoc->m_data[pageIndex][iItemIndex][pDoc->m_rowid].data());
						pDoc->m_db << sql
							<< k
							<< v;
					}
					pDoc->m_data[pageIndex][iItemIndex][iSubItem] = newtext;
					pDoc->m_data[pageIndex][iItemIndex][iSubItem - 1] = k;
				}
				else if (pDoc->m_table.Find(_T("'pinyin'")) != -1 && std::wstring(lvc.pszText) == L"key") {
					sql.Format(_T("update %s set jp = ? , key = ? where _rowid_ = %s;"), pDoc->m_table, pDoc->m_data[pageIndex][iItemIndex][pDoc->m_rowid].data());
					std::wstring wstr = newtext.GetString();
					std::wstring szmstr = dbother::getpyszm(wstr);
					pDoc->m_db << sql
						<< szmstr
						<< wstr;
					pDoc->m_data[pageIndex][iItemIndex][iSubItem] = newtext;
					if (pDoc->m_pyjp > -1) { pDoc->m_data[pageIndex][iItemIndex][pDoc->m_pyjp] = szmstr; }
				}
				else {
					sql.Format(_T("update %s set %s = ? where _rowid_ = %s;"), pDoc->m_table, lvc.pszText, pDoc->m_data[pageIndex][iItemIndex][pDoc->m_rowid].data());
					pDoc->m_db << sql
						<< newtext.GetString();
					pDoc->m_data[pageIndex][iItemIndex][iSubItem] = newtext;
				}
				parent->ReFresh();
				parent->UpdateRichEdit();
			}
			catch (sqlite::sqlite_exception& e) {
				errcode=e.get_code();
				hotkey = 0;
				UnregisterHotKey(m_hWnd, 0x801B);
				UnregisterHotKey(m_hWnd, 0x800D);
				UnregisterHotKey(m_hWnd, 0x8009);
				UnregisterHotKey(m_hWnd, 0x8409);
				UnregisterHotKey(m_hWnd, 0x8028);
				UnregisterHotKey(m_hWnd, 0x8026);
				errtext = e.get_msg();
				SetTimer(1, 20, 0);
			}
		}
	}
	SetFocus();
	if (hotkey == 0) {
		UnregisterHotKey(m_hWnd, 0x801B);
		UnregisterHotKey(m_hWnd, 0x800D);
		UnregisterHotKey(m_hWnd, 0x8009);
		UnregisterHotKey(m_hWnd, 0x8409);
		UnregisterHotKey(m_hWnd, 0x8028);
		UnregisterHotKey(m_hWnd, 0x8026);
	}
	pDoc->m_newrow = false;
}

void CDBListCtrl::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nIDEvent)
	{
	case 1:
		KillTimer(1);
		MessageBoxA(*this, errtext.data(), 0, 0);
		break;
	case 2:
		KillTimer(2);
		CDBBrowserView *parent = (CDBBrowserView*)GetParent();
		SetItemState(ItemIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
		SetSelectionMark(ItemIndex);
		parent->EditCell(ItemIndex, iSubItem);
		break;
	}
	CListCtrl::OnTimer(nIDEvent);
}

void CDBListCtrl::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	hotkey = nKey2;
	CDBBrowserView *parent = (CDBBrowserView*)GetParent();
	ItemIndex = iItemIndex + (parent->GetDocument()->m_pagesize) * pageIndex;
	m_Edit.SendMessage(WM_KILLFOCUS, 0, 0);
	if (errcode) { hotkey = 0; }
	else {
		if (nHotKeyId == 0x8009) {
			iSubItem++;
			if (iSubItem == parent->GetDocument()->m_rowid) { iSubItem++; }
		}
		else if (nHotKeyId == 0x8409) {
			iSubItem--;
			LV_COLUMN lvc;
			TCHAR szText[16];
			lvc.mask = LVCF_TEXT;
			lvc.pszText = szText;
			lvc.cchTextMax = 16;
			GetColumn(iSubItem, &lvc);
			if (std::wstring(lvc.pszText) == L"jp") { iSubItem--; }
			if (iSubItem == parent->GetDocument()->m_rowid) { iSubItem--; }
		}
		if (iSubItem < 0) {
			if (ItemIndex > 0) {
				SetItemState(ItemIndex, 0, LVIS_SELECTED | LVIS_FOCUSED);
				SetSelectionMark(-1);
				ItemIndex--; iSubItem = GetHeaderCtrl()->GetItemCount() - 1;
			}
			else { hotkey = 0; }
		}
		else if (iSubItem > GetHeaderCtrl()->GetItemCount() - 1) {
			if (ItemIndex < GetItemCount() - 1) {
				SetItemState(ItemIndex, 0, LVIS_SELECTED | LVIS_FOCUSED);
				SetSelectionMark(-1);
				ItemIndex++; iSubItem = 0;
				if (iSubItem == parent->GetDocument()->m_rowid) { iSubItem++; }
				LV_COLUMN lvc;
				TCHAR szText[16];
				lvc.mask = LVCF_TEXT;
				lvc.pszText = szText;
				lvc.cchTextMax = 16;
				GetColumn(iSubItem, &lvc);
				if (std::wstring(lvc.pszText) == L"jp") { iSubItem++; }
			}
			else { hotkey = 0; ((CDBBrowserApp*)AfxGetApp())->OnEditInsert(); return; }
		}
		else if (nHotKeyId == 0x8009 || nHotKeyId == 0x8409) {}
		else if (nHotKeyId == 0x8028) {
			if (ItemIndex < GetItemCount() - 1) {
				SetItemState(ItemIndex, 0, LVIS_SELECTED | LVIS_FOCUSED);
				SetSelectionMark(-1);
				ItemIndex++;
			}
			else { hotkey = 0; }
		}
		else if (nHotKeyId == 0x8026) {
			if (ItemIndex > 0) {
				SetItemState(ItemIndex, 0, LVIS_SELECTED | LVIS_FOCUSED);
				SetSelectionMark(-1);
				ItemIndex--;
			}
			else { hotkey = 0; }
		}
		else { hotkey = 0; }
	}
	
	if (hotkey) {
		parent->EditCell(ItemIndex, iSubItem);
	}
	else {
		UnregisterHotKey(m_hWnd, 0x801B);
		UnregisterHotKey(m_hWnd, 0x800D);
		UnregisterHotKey(m_hWnd, 0x8009);
		UnregisterHotKey(m_hWnd, 0x8409);
		UnregisterHotKey(m_hWnd, 0x8028);
		UnregisterHotKey(m_hWnd, 0x8026);
	}
	hotkey = 0;
	CListCtrl::OnHotKey(nHotKeyId, nKey1, nKey2);
}


void CDBBrowserView::EditCell(int iItem, int iSubItem)
{
	// TODO: 在此处添加实现代码.
	CDBBrowserDoc *pDoc = GetDocument();
	int iItemIndex = iItem % (pDoc->m_pagesize);
	int pageIndex = iItem / (pDoc->m_pagesize);
	if (pDoc->m_rowid > -1 && iSubItem != pDoc->m_rowid) {
		CRect rc;
		m_List.EnsureVisible(iItem, TRUE);
		m_List.SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		m_List.SetSelectionMark(iItem);
		m_List.GetSubItemRect(iItem, iSubItem, LVIR_LABEL, rc);
		m_List.m_Edit.MoveWindow(&rc);
		m_List.pageIndex = -1;
		m_List.iItemIndex = -1;
		m_List.iSubItem = -1;
		if (pDoc->m_data.find(pageIndex) != pDoc->m_data.end() && iItemIndex < pDoc->m_data[pageIndex].size()) {
			m_List.ItemText = pDoc->m_data[pageIndex][iItemIndex][iSubItem].data();
			m_List.m_Edit.SetWindowText(m_List.ItemText);
			m_List.pageIndex = pageIndex; m_List.iItemIndex = iItemIndex; m_List.iSubItem = iSubItem;
		}
		else {
			m_List.pageIndex = -1; m_List.iItemIndex = -1; m_List.iSubItem = -1;
			return;
		}
		m_List.m_Edit.ShowWindow(SW_SHOW);
		m_List.m_Edit.SetFocus();
		m_List.m_Edit.SetSel(0, -1);
		if (m_List.hotkey == 0) {
			RegisterHotKey(m_List.m_hWnd, 0x801B, 0, 0x1B);	//Esc
			RegisterHotKey(m_List.m_hWnd, 0x800D, 0, 0x0D);	//Enter
			RegisterHotKey(m_List.m_hWnd, 0x8009, 0, 0x09);	//Tab
			RegisterHotKey(m_List.m_hWnd, 0x8409, 4, 0x09);	//Shift+Tab
			RegisterHotKey(m_List.m_hWnd, 0x8028, 0, 0x28);	//Down
			RegisterHotKey(m_List.m_hWnd, 0x8026, 0, 0x26);	//Up
		}
	}
	m_List.hotkey = 0;
	m_List.errcode = 0;
}



void CDBBrowserView::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDBBrowserDoc *pDoc = GetDocument();
	WCHAR wcStr[MAX_PATH] = L"";
	TCHAR drive[MAX_PATH] = L"";
	TCHAR dir[MAX_PATH] = L"";
	TCHAR fileName[MAX_PATH] = L"";
	TCHAR ext[MAX_PATH] = L"";
	if (pDoc->m_tbl == L"functions") {
		readd:
		int begin = pDoc->m_itemcount / pDoc->m_pagesize;
		try {
			if (pDoc->m_autotrans && !pDoc->m_transaction) {
				pDoc->m_db << "begin;";
				pDoc->m_transaction = true;
			}
			int DropCount = DragQueryFile(hDropInfo, -1, NULL, 0);
			for (int i = 0; i < DropCount; i++) {
				memset(wcStr, 0, MAX_PATH);
				memset(drive, 0, MAX_PATH);
				memset(dir, 0, MAX_PATH);
				memset(fileName, 0, MAX_PATH);
				memset(ext, 0, MAX_PATH);
				DragQueryFile(hDropInfo, i, wcStr, MAX_PATH);
				_wsplitpath_s(wcStr, drive, MAX_PATH, dir, MAX_PATH, fileName, MAX_PATH, ext, MAX_PATH);
				pDoc->m_db << L"insert into " + pDoc->m_table + L" default values;";
				unsigned int rowid = pDoc->m_db.last_insert_rowid();
				pDoc->m_db << L"update " + pDoc->m_table + L" set value = ? , comment = ? where rowid = ?;"
					<< wcStr
					<< fileName
					<< rowid;
				pDoc->m_itemcount++;
				pDoc->m_rowcount++;
			}
		}
		catch (sqlite::sqlite_exception& e) {
			MessageBoxA(AfxGetMainWnd()->m_hWnd, e.get_msg(), 0, 0);
		}
		pDoc->m_data.erase(pDoc->m_data.find(begin), pDoc->m_data.end());
		m_List.SetSelectionMark(-1);
		m_List.SetItemCount(pDoc->m_itemcount);
		auto pStatusBar = (CMFCRibbonStatusBar*)((CFrameWndEx*)AfxGetMainWnd())->GetPane(AFX_IDW_STATUS_BAR);
		auto pStatusBarPane = (CMFCRibbonStatusBarPane*)(pStatusBar->FindElement(ID_STATUSBAR_PANE2));
		CString jls;
		jls.Format(_T("共%d条"), pDoc->m_rowcount);
		pStatusBarPane->SetText(jls);
		pStatusBarPane->Redraw();
		ReFresh();
		DragFinish(hDropInfo);
	}
	else {
		int DropCount = DragQueryFile(hDropInfo, -1, NULL, 0);
		for (int i = 0; i < DropCount; i++) {
			memset(wcStr, 0, MAX_PATH);
			memset(drive, 0, MAX_PATH);
			memset(dir, 0, MAX_PATH);
			memset(fileName, 0, MAX_PATH);
			memset(ext, 0, MAX_PATH);
			DragQueryFile(hDropInfo, i, wcStr, MAX_PATH);
			_wsplitpath_s(wcStr, drive, MAX_PATH, dir, MAX_PATH, fileName, MAX_PATH, ext, MAX_PATH);
			std::wstring se = ext;
			if (std::regex_search(se, std::wregex(L"\\.(txt|csv)", std::wregex::icase))) {
				((CDBBrowserApp*)AfxGetApp())->ImportCSVToDB(wcStr, fileName);
			}
			else if (std::regex_search(se, std::wregex(L"\\.db3?$", std::wregex::icase))) {
				((CDBBrowserApp*)AfxGetApp())->OpenDB(wcStr, _T("main"));
			}
			else {
				((CDBBrowserApp*)AfxGetApp())->SelectNode(_T("functions"));
				goto readd;
			}
		}
		DragFinish(hDropInfo);
	}
	CView::OnDropFiles(hDropInfo);
}
